﻿using AutoMapper;
using Mapster;
using MediatR;
using ShineTech.Domain.Models.Kanbans;
using ShineTech.Domain.Models.Missons;
using ShineTech.Domain.SeedWork;
using ShineTech.Web.Kanbans.Commands;
using ShineTech.Web.Missons.Commands;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;


namespace ShineTech.Web.Kanbans
{
    public class KanbanCommandHandler :
        IRequestHandler<CreateKanbanCommand, KanbanDTO>,
        IRequestHandler<UpdateKanbanCommand, KanbanDTO>,
        IRequestHandler<CreateShareCommand, ShareDTO>,
        IRequestHandler<KanbanByIdQuery, KanbanDTO>,
        IRequestHandler<KanbansByFiltersQuery, IEnumerable<KanbanDTO>>,
        IRequestHandler<ConfirmShareCommand, ShareDTO>,
        IRequestHandler<KanbansByFiltersPageQuery, PageData<KanbanDTO>>,
        INotificationHandler<DeleteKanbanCommand>

    {
        private readonly IUnitOfWork _uow;
        private readonly IKanbanRepository _KanbanRepository;
        private readonly IShareRepository _ShareRepository;
        private readonly IMapper _mapper;

        public KanbanCommandHandler(IKanbanRepository kanbanRepository, IShareRepository shareRepository, IUnitOfWork uow, IMapper mapper)
        {
            _KanbanRepository = kanbanRepository;
            _ShareRepository = shareRepository;
            _uow = uow;
            _mapper = mapper;
        }


        /// <summary>
        /// 查看看板详情
        /// </summary>
        /// <param name="request"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        public async Task<KanbanDTO> Handle(KanbanByIdQuery request, CancellationToken cancellationToken)
        {
            Kanban kanban = await _KanbanRepository.FindOneAsync(new KanbanByIdSpecification(request.Id));
            return _mapper.Map<KanbanDTO>(kanban);
        }
        /// <summary>
        /// 查看所有看板
        /// </summary>
        /// <param name="request"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        public async Task<IEnumerable<KanbanDTO>> Handle(KanbansByFiltersQuery request, CancellationToken cancellationToken)
        {
            IEnumerable<Share> shares = await _ShareRepository.FindAllAsync(new ShareByToUserIdSpecification(request.UserId.Value));

            var KanbanIds = shares.Select(x => x.KanbanId).ToList();
            IEnumerable<Kanban> kanbans = await _KanbanRepository.FindAllAsync(new KanbansByFiltersSpecification(request.Name ?? string.Empty, request.UserId, KanbanIds));
            return _mapper.Map<IEnumerable<KanbanDTO>>(kanbans);
        }/// <summary>
         /// 分页查看所有看板
         /// </summary>
         /// <param name="request"></param>
         /// <param name="cancellationToken"></param>
         /// <returns></returns>
        public async Task<PageData<KanbanDTO>> Handle(KanbansByFiltersPageQuery request, CancellationToken cancellationToken)
        {
            IEnumerable<Share> shares = await _ShareRepository.FindAllAsync(new ShareByToUserIdSpecification(request.UserId.Value));

            var KanbanIds = shares.Select(x => x.KanbanId).ToList();
            var kanbans = await _KanbanRepository.GetPageData(
                new KanbansByFiltersSpecification(request.Name ?? string.Empty,
                    request.UserId,
                    KanbanIds),
                request.PageIndex,
                request.PageSize);
            return kanbans.Adapt<PageData<KanbanDTO>>();
        }
        /// <summary>
        /// 创建任务看板
        /// </summary>
        /// <param name="request"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        public async Task<KanbanDTO> Handle(CreateKanbanCommand request, CancellationToken cancellationToken)
        {

            Kanban kanban = new Kanban(request.Name, request.CreatedUserId, request.CreatedUserName, request.CreatedTime);
            _KanbanRepository.Add(kanban);
            await _uow.CommitAsync(cancellationToken);
            return _mapper.Map<KanbanDTO>(kanban);
        }

        /// <summary>
        /// 更新任务看板
        /// </summary>
        /// <param name="request"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        public async Task<KanbanDTO> Handle(UpdateKanbanCommand request, CancellationToken cancellationToken)
        {

            Kanban kanban = await _KanbanRepository.FindOneAsync(new KanbanByIdSpecification(request.Id));
            if (kanban == null)
                throw CustomException.NotFound("kanban");
            kanban.Update(request.Name);
            _KanbanRepository.Update(kanban);
            await _uow.CommitAsync(cancellationToken);
            return _mapper.Map<KanbanDTO>(kanban);
        }

        /// <summary>
        /// 共享列表
        /// </summary>
        /// <param name="request"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        public async Task<ShareDTO> Handle(CreateShareCommand request, CancellationToken cancellationToken)
        {
            Share share = new Share(request.SendUserId, request.ToUserId, false, request.KanbanId, request.SendEmail, request.ToEmail);
            _ShareRepository.Add(share);
            await _uow.CommitAsync(cancellationToken);
            return _mapper.Map<ShareDTO>(share);
        }

        /// <summary>
        /// 确认分享
        /// </summary>
        /// <param name="request"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        public async Task<ShareDTO> Handle(ConfirmShareCommand request, CancellationToken cancellationToken)
        {
            Share share = await _ShareRepository.FindOneAsync(new ShareByIdSpecification(request.ShareId));
            if (share.ToUserId != request.ToUserId)
            {
                throw new Exception("这不是分享给你的链接");
            }
            share.IsConfirm = true;
            _ShareRepository.Update(share);
            await _uow.CommitAsync(cancellationToken);
            return _mapper.Map<ShareDTO>(share);

        }
        /// <summary>
        /// 删除
        /// </summary>
        /// <param name="notification"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        public async Task Handle(DeleteKanbanCommand notification, CancellationToken cancellationToken)
        {

            Kanban kanban = await _KanbanRepository.FindOneAsync(new KanbanByIdSpecification(notification.Id));
            if (kanban == null)
                throw CustomException.NotFound("kanban");

            _KanbanRepository.Remove(kanban);
            await _uow.CommitAsync(cancellationToken);
        }
    }
}
